package top.z.work.framework.web.config;

import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.filter.SaServletFilter;
import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.router.SaHttpMethod;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import top.z.work.framework.web.filter.LoggerAccessFilter;
import top.z.work.framework.web.interceptor.ApiAccessLogInterceptor;
import top.z.work.module.system.api.logger.SystemLoggerAccessApi;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Configuration
public class WorkWebAutoConfiguration implements WebMvcConfigurer {

    // 登录超时
    @Value("${top-work.token.exclude-url}")
    List<String> excludeUrl = new ArrayList<>();

    @Resource
    SystemLoggerAccessApi systemLoggerAccessApi;

    /**
     * 创建 ApiAccessLogFilter Bean，记录 API 请求日志
     */
    @Bean
    @ConditionalOnExpression("${top-work.access-log.enable:true}")
    public FilterRegistrationBean<LoggerAccessFilter> apiLoggerAccessFilter() {
        FilterRegistrationBean<LoggerAccessFilter> bean = new FilterRegistrationBean<>(
                new LoggerAccessFilter(systemLoggerAccessApi)
        );
        bean.setOrder(-103);
        return bean;
    }

    /**
     * 注册拦截器
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // api 拦截器
        registry.addInterceptor(new ApiAccessLogInterceptor());
        // 注册 Sa-Token 拦截器, 定义详细认证规则 
        registry.addInterceptor(new SaInterceptor(handler -> {
            SaRouter.match("/**")
                    .notMatch(excludeUrl)
                    .check(r -> StpUtil.checkLogin());
        })).addPathPatterns("/**");
    }

    /**
     * 注册跨域
     */
    @Bean
    public SaServletFilter saServletFilter() {
        log.info("排除鉴权的URL: {}", excludeUrl);
        return new SaServletFilter()
                .addInclude("/**")
                .setBeforeAuth(auth -> {
                    SaHolder.getResponse()
                            // 允许指定域访问跨域资源
                            .setHeader("Access-Control-Allow-Origin", "*")
                            // 允许所有请求方式
                            .setHeader("Access-Control-Allow-Methods", "*")
                            // 允许的header参数
                            .setHeader("Access-Control-Allow-Headers", "*")
                            // 有效时间
                            .setHeader("Access-Control-Max-Age", "3600");

                    // 如果是预检请求, 则立即返回到前端
                    SaRouter.match(SaHttpMethod.OPTIONS).free(r -> {
                    }).back();

                });
    }

}
